<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <input id="box" v-model='name' type='text' />
    <input id="box2" v-model='name' type='text' />
    {{name}}
    <div>
      <p>{{name}}</p>
    </div>
  </div>
  <script>
    //{{name}}

    let re = /\{\{([^}]*)\}\}/g

    class DateView {
      constructor(data) {
        this.nodes = [];
        this.data = data;
      }

      //绑定节点
      bind(node) {
        this.nodes.push(node);
      }

      //设置
      update() {
        this.nodes.forEach(node => {
          if (node.nodeType === 1) {
            node.value = this.data;

          }
          if (node.nodeType === 3) {
            //node.dd = {{name}}
            node.textContent = node.dd.replace(re, function ($0, $1) {
              return data[$1].data;
            })
          }
        })
      }


      setter(newVal) {
        if (this.data != newVal) {
          this.data = newVal;
          this.update();
        }
      }

      getter() {
        return this.data;
      }


    }


    /* 
      初始化数据
    */
    let data = {
      name: new DateView('谷子多'),
      name2: new DateView('谷子多2'),
      name3: new DateView('谷子多3'),
    }

    function compile(ele) {
      ele = document.querySelector(ele);
      //文档碎片
      let fragment = document.createDocumentFragment();
      //第一个子节点(元素节点:input、文本节点:name、属性节点: 行间样式)
      let child = ele.firstChild

      while (child) {
        fragment.appendChild(child);
        child = ele.firstChild
      }

      // console.log(fragment.childNodes);

      function forF(fragment) {
        Array.from(fragment.childNodes).forEach(node => {

          //获取元素节点
          if (node.nodeType === 1) {
            // console.log(node.attributes);
            Array.from(node.attributes).forEach(attr => {
              // console.log(attr.value);
              let {
                name,
                value
              } = attr;
              if (name.includes('v-')) {
                //找到了v- 标识
                data[value].bind(node);
                node.addEventListener('input', function (ev) {
                  // console.log(ev.target.value);
                  data[value].setter(ev.target.value)
                  // console.log(data[value].getter());

                })
              }

            })

          }


          //获取文本节点
          if (node.nodeType === 3) {
            // console.dir(node);
            let txt = node.textContent;
            if (re.test(txt)) {
              // console.log(node)
              txt.replace(re, function ($0, $1) {
                // console.log($0,$1)
                data[$1].bind(node);
                node.dd = txt;
              })
            }
          }

          if (node.childNodes.length) {
            forF(node)
          }

        })
      }

      forF(fragment);


      //批量触发器
      Object.keys(data).forEach(e => {
        data[e].update();
      });

      //显示到页面
      ele.appendChild(fragment);



    }


    compile('#app');
  </script>
</body>

</html>